import os
import subprocess


class VideoSpeedChanger:
    """
    视频倍速处理类：可批量调整视频（含音频）播放速度
    """

    def __init__(self, input_dir: str, output_dir: str, speed: float):
        """
        初始化参数
        :param input_dir: 输入文件夹路径
        :param output_dir: 输出文件夹路径
        :param speed: 播放速度（float，例如 0.5=慢放，2.0=加快）
        """
        self.input_dir = input_dir
        self.output_dir = output_dir
        self.speed = speed

        os.makedirs(output_dir, exist_ok=True)

    def _get_audio_filter(self) -> str:
        """
        根据倍速生成 ffmpeg 音频过滤器
        atempo 限制在 [0.5, 2.0]，所以要分段叠加
        """
        speed = self.speed
        filters = []

        if 0.5 <= speed <= 2.0:
            filters.append(f"atempo={speed}")
        else:
            remaining = speed
            while remaining > 2.0:
                filters.append("atempo=2.0")
                remaining /= 2.0
            while remaining < 0.5:
                filters.append("atempo=0.5")
                remaining /= 0.5
            filters.append(f"atempo={remaining}")

        return ",".join(filters)

    def process_all(self):
        """
        批量处理文件夹内所有视频
        """
        count = 0
        for filename in os.listdir(self.input_dir):
            if not filename.lower().endswith(('.mp4', '.mov', '.avi', '.mkv', '.flv', '.wmv', '.webm')):
                continue

            input_path = os.path.join(self.input_dir, filename)
            output_path = os.path.join(self.output_dir, filename)

            video_filter = f"setpts={1/self.speed}*PTS"
            audio_filter = self._get_audio_filter()

            cmd = [
                "ffmpeg", "-y", "-i", input_path,
                "-filter:v", video_filter,
                "-filter:a", audio_filter,
                output_path
            ]

            print(f"🎬 正在处理：{filename}  → 倍速：x{self.speed}")
            try:
                subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
                count += 1
            except subprocess.CalledProcessError as e:
                print(f"❌ 出错：{filename}（原因：{e}）")
                continue

        print(f"\n✅ 全部完成，共处理 {count} 个视频。")


# 示例使用
if __name__ == "__main__":
    changer = VideoSpeedChanger(
        input_dir=r"C:\Users\33720\Desktop\N1听力合集 无“叮”声，沉沁式听日语\《生活情景日语图解》 文章音频 _听力练习Over",
        output_dir=r"C:\Users\33720\Desktop\N1听力合集 无“叮”声，沉沁式听日语\《生活情景日语图解》 文章音频 _听力练习CMP31.1",
        speed=1.15
    )
    changer.process_all()
